package com.samp.tools.guava;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import com.samp.solr.file2solr.DataAnalyze;
import org.apache.commons.codec.binary.Base64;

import java.io.BufferedReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

/**
 * 布隆过滤器通常用来去重，对于在集合中的元素，它可以准确的判断出来，已经存在 。
 * 但是对于不在集合中的元素，它有一定的概念也认为存在于集合中，也就是误判率。
 * 如果还要更快的实现，可参见 ：http://www.importnew.com/23301.html
 */
public class BloomFilterDemo {
    private static int size = 20000;
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.00001);

    private static BloomFilter<String> strBoomFilter =
            BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), size, 0.0001F);


    /**
     *
     */
    private static void testBloomFilter(){
        for (int i = 0; i < size; i++) {
            bloomFilter.put(i);
        }

        for (int i = 0; i < size; i++) {
            if (!bloomFilter.mightContain(i)) {
                System.out.println("error, data in filter.");
            }
        }

        List<Integer> list = new ArrayList<Integer>(1000);
        for (int i = size + 10000; i < size + 200000; i++) {
            if (bloomFilter.mightContain(i)) {
                list.add(i);
            }
        }
        System.out.println("不在集合中，确认为在集合中比率：" + list.size());
    }

    private static String md5(String text){
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] strBytes = text.getBytes();
            md5.update(strBytes);
            byte[] resultBytes = md5.digest();
            String result = Base64.encodeBase64String(resultBytes);
            return result;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    private static void checkDuplString(){
        String rawPath = "D:\\gcc-omcp\\temp\\base64_intention\\040102_final.txt";
        Path filePath = Paths.get(rawPath);
        BufferedReader bufferReader = null;
        List<String> dupList = new ArrayList<>();
        List<String> totalList = new ArrayList<>();
        try {
            bufferReader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8);
            String line;
            while( (line = bufferReader.readLine()) != null ){
                totalList.add(DataAnalyze.transferText(line));
                String transText = DataAnalyze.transferText(line);
//                if( transText.equals("I贷 情况 查询 还款 需要 action.name=查询#target.name=还款#target.params1=还款信息#target.params2=default")){
//                    System.out.println("====================");
//                    System.out.println(line);
//                }
                if( strBoomFilter.mightContain(transText) ){
//                    System.out.println("exist:"+transText);
                    dupList.add(DataAnalyze.transferText(line));
                }else {
                    strBoomFilter.put(transText);
                }

            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                bufferReader.close();
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }
        //检查性能
        System.out.println("dupList size = "+dupList.size());
        int success_data = 0;
        int error_data = 0;
        for( String dupData: dupList ){
            int i = 0 ;
            for(int j = 0 ; j < totalList.size() ; j++){
                String allData = totalList.get(j);
                if( dupData.equals(allData) ){
//                    System.out.println("found "+dupData+" at index: "+j);
                    i++;
                }
            }
            if( i > 1 ) {
                success_data++;
//                System.out.println(dupData + " found times :" + i);
            }else {
                error_data++;
                System.out.println(dupData+" only one times found ");
            }
        }
        System.out.println("success_data="+success_data);
        System.out.println("error_data="+error_data);
        System.out.println(strBoomFilter.expectedFpp());
//        System.out.println(strBoomFilter.mightContain(
//                DataAnalyze.transferText("我 查询 像 我 我 车辆 贷款 $姓名 1年 像 我 贷款 能不能\t咨询 产品 申请条件及材料")));
//        System.out.println(strBoomFilter.mightContain(
//                DataAnalyze.transferText("我 现在 有 贷款 需求 我 查询 宅E经营贷 最高 贷款 金额 多少\t咨询 产品 额度及期限")));
//        System.out.println(strBoomFilter.mightContain(
//                DataAnalyze.transferText("我 需要 还款 把 欠 企业 $姓名 还款 操作\t咨询 还款 还款操作")));
//        System.out.println(strBoomFilter.mightContain(
//                DataAnalyze.transferText("查询 在 普惠 APP 怎么  我  卡拉 自己 分\t咨询 APP 克拉分")));
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        checkDuplString();
        long cost = System.currentTimeMillis()-start;
        System.out.println("cost="+cost);
    }
}
